#ifndef __HTTP_PROT_RESPONSE_H_
#define __HTTP_PROT_RESPONSE_H_

#include <string>
#include <vector>
#include <map>
#include "httpprot_status.h"


namespace httpprot
{
	class Response
	{
	public:
		/**
		 * \brief The status of Request after parsing data
		 */
		enum ParseStatus
		{
			/**
			 * \brief Parsing finished successfully
			 */
			PARSE_OK,

			/**
			 * \brief Parsing cannot be finished because the request in not complete
			 */
			PARSE_INCOMPLETE,

			/**
			 * \brief Parsing failed, may be data is not a valid HTTP request
			 */
			PARSE_ERROR
		};

	public:
		Response( ) :
			m_status( STATUS_200_OK )
		{
		}

		~Response( )
		{
		}

		ParseStatus Parse( const char * responseData, unsigned int responseDataLength )
		{
			return PARSE_INCOMPLETE;
		}

		Status GetStatus( ) const
		{
			return m_status;
		}

		void SetStatus( Status status )
		{
			m_status = status;
		}

		bool GetHeader( const std::string& header, std::string& valueOut )
		{
			std::map< std::string, std::string >::iterator it = m_headers.find( header );
			if( it == m_headers.end( ) )
				return false;
			valueOut = (*it).second;
			return true;
		}

		void AddHeader( const std::string& header, const std::string& value )
		{
			m_headers[ header ] = value;
			if( header == "Content-Length" )
				updateContentLength( );
		}

		const std::vector< char >& GetMessage( ) const
		{
			return m_message;
		}

		template< typename ContainerType >
		void AddBytesToMessage( const ContainerType& message )
		{
			m_message.insert( m_message.end( ), message.begin( ), message.end( ) );
			updateContentLength( );
		}

		void AddBytesToMessage( const char * message )
		{
			unsigned int length = strlen( message );
			m_message.insert( m_message.end( ), message, message + length );
			if( length )
				updateContentLength( );
		}

		void ToBuffer( std::vector< char >& bufferOut );

	private:
		void updateContentLength( );

		void storeChar( char c, std::vector< char >& bufferOut );
		void storeCString( const char * cString, std::vector< char >& bufferOut );
		void storeString( const std::string& s, std::vector< char >& bufferOut );
		void storeVector( const std::vector< char >& v, std::vector< char >& bufferOut );

	private:
		Status m_status;
		std::map< std::string, std::string > m_headers;
		std::vector< char > m_message;
	};
};

#endif